#define GTK_ENABLE_BROKEN

#include <gtk/gtk.h>

//typedef struct _GtkTree GtkTree;
//#define GTK_TREE(x) ((GtkTree*)x)

static void cb_itemsignal(GtkWidget *item,gchar *signame){
	GtkLabel *label = GTK_LABEL(GTK_BIN(item)->child);
	gchar *name;
	gtk_label_get(label,&name);
	printf("%s called for item %s->%p,level %d\n",signame,name,item,
		GTK_TREE(item->parent)->level);
}

static void cb_unselect_child(GtkWidget *root_tree,GtkWidget *child,GtkWidget *subtree){
	printf("%s called for root tree %p , subtree %p , child %p\n",__func__,
		root_tree,subtree,child);
}

static void cb_select_child(GtkWidget *root_tree,GtkWidget *child,GtkWidget *subtree){
	printf("%s called for root tree %p,subtree %p ,child %p\n",__func__,
		root_tree,subtree,child);
}

static void cb_selection_changed(GtkWidget *tree){
	printf("%s : selected objects are:\n",__func__);
	GList *i = GTK_TREE_SELECTION_OLD(tree);
	while(i){
		gchar *name;
		GtkLabel *label;
		GtkWidget *item;
		item = GTK_WIDGET(i->data);
		label = GTK_LABEL(GTK_BIN(item)->child);
		gtk_label_get(label,&name);
		printf("\t%s on level %d\n",name,GTK_TREE(item->parent)->level);
		i = i->next;
	}

}

int main(int argc,char **argv){
	GtkWidget *w,*scrolled_win,*tree;
	static gchar *item_names[] = {"Foo","Bar","Baz","Quux","Maurice"};
	#define ITEM_COUNT (sizeof(item_names)/sizeof(gchar*))

	gtk_init(&argc,&argv);
	w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	gtk_signal_connect(GTK_OBJECT(w),"delete_event",G_CALLBACK(gtk_main_quit),NULL);
	gtk_container_set_border_width(GTK_CONTAINER(w),5);

	scrolled_win = gtk_scrolled_window_new(NULL,NULL);
	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_win),
		GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
	gtk_widget_set_usize(scrolled_win,150,200);
	gtk_container_add(GTK_CONTAINER(w),scrolled_win);

	tree = gtk_tree_new();
	printf("%s:root tree is %p\n",__func__,tree);
	gtk_signal_connect(GTK_OBJECT(tree),"select_child",G_CALLBACK(cb_select_child),tree);
	gtk_signal_connect(GTK_OBJECT(tree),"unselect_child",G_CALLBACK(cb_unselect_child),tree);
	gtk_signal_connect(GTK_OBJECT(tree),"selection_changed",
		G_CALLBACK(cb_selection_changed),tree);
	gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_win),tree);
	gtk_tree_set_selection_mode(GTK_TREE(tree),GTK_SELECTION_MULTIPLE);

	for(int i = 0;i<ITEM_COUNT;i++){
		GtkWidget *subtree,*item;
		item = gtk_tree_item_new_with_label(item_names[i]);
		gtk_signal_connect(GTK_OBJECT(item),"select",G_CALLBACK(cb_itemsignal),"select");
		gtk_signal_connect(GTK_OBJECT(item),"deselect",G_CALLBACK(cb_itemsignal),"deselect");
		gtk_signal_connect(GTK_OBJECT(item),"toggle",G_CALLBACK(cb_itemsignal),"toggle");
		gtk_signal_connect(GTK_OBJECT(item),"expand",G_CALLBACK(cb_itemsignal),"expand");
		gtk_signal_connect(GTK_OBJECT(item),"collapse",G_CALLBACK(cb_itemsignal),"collapse");

		gtk_tree_append(GTK_TREE(tree),item);
		subtree = gtk_tree_new();
		gtk_signal_connect(GTK_OBJECT(subtree),"select_child",G_CALLBACK(cb_select_child),subtree);
		gtk_signal_connect(GTK_OBJECT(subtree),"unselect_child",G_CALLBACK(cb_unselect_child),subtree);
		gtk_tree_set_selection_mode(GTK_TREE(subtree),GTK_SELECTION_SINGLE);
		gtk_tree_set_view_mode(GTK_TREE(subtree),GTK_TREE_VIEW_ITEM);
		gtk_tree_item_set_subtree(GTK_TREE_ITEM(item),subtree);
		for(int j = 0;j < ITEM_COUNT;j++){
			GtkWidget *subitem = gtk_tree_item_new_with_label(item_names[j]);
			gtk_signal_connect(GTK_OBJECT(subitem),"select",
				G_CALLBACK(cb_itemsignal),"select");
			gtk_signal_connect(GTK_OBJECT(subitem),"deselect",
				G_CALLBACK(cb_itemsignal),"deselect");
			gtk_signal_connect(GTK_OBJECT(subitem),"toggle",
				G_CALLBACK(cb_itemsignal),"toggle");
			gtk_signal_connect(GTK_OBJECT(subitem),"expand",
				G_CALLBACK(cb_itemsignal),"expand");
			gtk_signal_connect(GTK_OBJECT(subitem),"collapse",
				G_CALLBACK(cb_itemsignal),"collapse");
			gtk_tree_append(GTK_TREE(subtree),subitem);
			gtk_widget_show(subitem);
		}
	}

	gtk_widget_show_all(w);
	gtk_main();

	return 0;
}